package cn.tedu.v6;

import java.io.*;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Scanner;

/**
 * 网络通讯---Socket【套接字】理解：互联网型java类
 *
 * 网络应用遵循的原则：
 * C/S架构 Client 客户端   Server   服务器   早期应用【手机app--手机应用】
 * JavaSE 桌面级软件--java并不擅长
 *
 * B/S加构 Browser浏览器端 Server 服务端后期应用【后台语言]
 * *JavaSE 做逻辑Mysql保存数据  Web---Java管理后台
 *
 * 客户端 类：Client----->网络通讯 Socket
 * 服务器端 类：Server----> 网络通讯 ServerSocket
 *
 * 网络通讯  ServerSocket、Socket--底层传输协议支持两种
 * TCP协议：可靠性号传输协议，基于字节流--传输低、安全性高【√传数据】
 * UDP协议：不可靠传输协议，基于数据报--传输高，安全低【游戏】
 * 以上两种协议，封装底层代码中
 *
 *
 * 需求：通过IP+端口    别人链接上自己    相互建议链接
 * 需求2：相互建议链接 ：开启服务端--客户端给服务端发送：文本
 *        提示：start()    写逻辑
 *   网络通讯 Socket，具备方法，支持标准流
 *     客户端|服务端-----Socket对象---调用方法
 *                                 getInputStream()获取输入流
 *                                 getOutputSream()获取输出流
 *
 */

/**
 * 聊天室Version2
 *
 * 功能：客户端--指定IP，端口号
 *      2.客户端给服务器发送文本
 *      3.客户端完成标准IO
 *      【新增】4.捕获异常，打印异常信息--异常全部抓住，用户明确提示
 *      5.关闭socket
 * 客户端
 */

/**
 * 聊天室 Version 2.1
 * 客户端基本不变：关闭socket、拓展增加IP
 *                          1.私有化IP
 *                          2.构造器，当前IP进行赋值
 *                          3.任意位置使用IP[读入知道对方IP]
 *
 */

/**
 * 多人聊天室 3
 * 功能：一个客户端与一个服务器端相互聊天
 * 1.客户端--连接服务器--第一件事：写出
 * 2.客户端--读入--存线程中，对应服务器的读入
 */

/**
 * 多人聊天室  Version3.1
 * 优化版本 ，功能：客户端与服务器端可以双向沟通
 *优化一：导入包开始优化
 * 2.动态数据全部封装到类上，代码更加易用
 * 3.读入和写出 操作定义---构造器 |功能
 *   构造器主要用于对象初始化，Client对象初始化：添加IP和端口号
 *                                      创建流添加
 *   优点1.减少代码重复和复杂度
 *      2.代码结构清晰
 *      3.客户端创建之初，明确具备读写功能
 *    构造器：读写定义
 *    start方法：保留读写功能
 *    参考Client  优化 Server
 * 问题1：标准IO流置空，线程中使用BufferedRead 无法到达【作用域不够】
 * 流置空问题更适合在短期、简单场景中使用，不一定保证对象正确释放
 * 有可能报出null，实际软件开发中使用JavaOOP封装思路替换置空方式
 * 置空流 方式         升级      JavaOOP  方式
 * 好处：①数据保护：本类下可访问，确保其他类无法直接访问
 *      ②易用性和安全性：置空操作--目的：赋值、关闭，紧邻try上
 *                      私有化属性--->便于修改
 */
public class Client {

 private static final String HOST="172.20.10.12";
   private static final Integer PORT=1019;
    private Socket socket;
    private String ip;
    private PrintWriter pw;
    private BufferedReader br;
    private String message;

    public Client() {
        try {
            socket = new Socket(HOST, PORT);
            ip = socket.getInetAddress().getHostAddress();
            br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF8"));
            pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), "UTF8")), true);
        }catch (SocketException e){
            System.out.println("连接被重置或断开");
        } catch (UnknownHostException e) {
            System.out.println("IP地址有问题，请询问服务器端！");
        } catch (IOException e) {
            System.out.println("客户端主动退出了：断开连接");
        }finally {

        }
    }
    public void start() {
        try {
            System.out.println("欢迎使用聊天室");
            Scanner input = new Scanner(System.in);
            try {
                String serverMessage = br.readLine();//服务器端：写“请输入用户名”
                System.out.println(serverMessage);
                //2.写出用户名
                String username = input.nextLine();
                //3.写出用户名，发给服务器
                pw.println(username);//写出给服务器端--获取账号
                //二、接收登陆密码提示
                //1.读入客户端--输出流
                serverMessage = br.readLine();//服务器端：写“输入密码”
                System.out.println(serverMessage);
                //2.写出密码
                String password = input.nextLine();
                //3.写出密码，发给服务器
                pw.println(password);
                serverMessage = br.readLine();
                System.out.println(serverMessage);

                //三、服务器端验证账号密码是否正确
                //3.1判断如果是“登陆成功，欢迎进入XX牌聊天室”前缀：登陆成功
                if (serverMessage.startsWith("登陆成功")) {
                    chat();//聊天功能
                }
            } catch (IOException e) {
                System.out.println("客户端断开了链接");
            }
        }
        finally {
            try{
            if (pw != null)
                pw.close();
            if(br!=null)
                    br.close();
                } catch (IOException e) {
                    System.out.println("服务器通讯内容失败~~");
                }
            if(socket!=null&&socket.isClosed()){
               System.out.println("客户端关闭成功");
               try {
                   socket.close();
               } catch (IOException e) {
                   System.out.println("客户端关闭失败");
               }
           }
        }
    }
    //读入
    //  while (true){
//String str=br.readLine();
    //  System.out.println("服务器说话"+str);
    //  }
public void chat(){
   Thread t1= new Thread(()->{
        try {
            while ((message=br.readLine())!=null){
                System.out.println("服务器端说："+message);
            }
        } catch (IOException e) {
            System.out.println("服务器端发来的消息断开了~");
        }
    });
   t1.start();
    System.out.println("客户端用户请输入文字：");
    Scanner input=new Scanner(System.in);
    while (true){
        String say=input.nextLine();
        pw.println("客户端说："+say);
        if(say.equalsIgnoreCase("exit")){
            break;
        }
    }
}
    public static void main(String[] args) {
        new Client().start();
    }
}


